package top.xia17.plugins.fast.common.database.jpa.custom;


import cn.hutool.core.util.StrUtil;
import jakarta.persistence.AttributeConverter;
import lombok.extern.slf4j.Slf4j;
import top.xia17.plugins.fast.common.crypto.asymmetric.RsaUtil;
import top.xia17.plugins.fast.common.exceptions.BadRequestException;
import top.xia17.plugins.fast.common.spring.SpringContextHolder;

import java.util.concurrent.locks.ReentrantLock;

/**
 * JPA字段的RSA加密转换器
 * @author xia17
 * @date 2021/1/6 17:01
 */
@Slf4j
public class RsaEncryptAttributeConverter implements AttributeConverter<String, String> {

    /** rsa加密工具 */
    private RsaUtil rsaUtil = null;
    /** 锁 */
    private final ReentrantLock reentrantLock = new ReentrantLock();

    /**
     * 存储到数据库时需要进行的操作
     * 这里进行rsa私钥加密
     * @param attribute 字段值
     * @return /
     */
    @Override
    public String convertToDatabaseColumn(String attribute) {
        if (StrUtil.isBlank(attribute)){
            return null;
        }
        return this.getRsaUtil().encryptStr(attribute);
    }

    /**
     * 从数据库读取到实体中需要进行的操作
     * 这里进行rsa私钥解密
     * @param dbData 字段值
     * @return /
     */
    @Override
    public String convertToEntityAttribute(String dbData) {
        if (StrUtil.isBlank(dbData)){
            return null;
        }
        return this.getRsaUtil().decryptStr(dbData);
    }



    /**
     * 获取加密、解密工具
     * 使用单例模式，使用同步锁达到线程安全的懒汉式单例
     * @return /
     */
    private RsaUtil getRsaUtil(){
        if (rsaUtil == null) {
            reentrantLock.lock();
            try {
                if (rsaUtil == null) {
                    // 从spring容器中获取rasUtil
                    this.rsaUtil = SpringContextHolder.getBean(RsaUtil.class);
                }
            } catch (RuntimeException e) {
                throw new BadRequestException("从容器中获取RsaUtil失败");
            } finally {
                reentrantLock.unlock();
            }
        }
        return rsaUtil;
    }


}
